home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Viewers / VideoStreamV1.0 / Source / mpegDecodeSrc / parseblock.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-12  |  9.1 KB  |  420 lines

  1. /*
  2.  * Copyright (c) 1992 The Regents of the University of California.
  3.  * All rights reserved.
  4.  * 
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation for any purpose, without fee, and without written agreement is
  7.  * hereby granted, provided that the above copyright notice and the following
  8.  * two paragraphs appear in all copies of this software.
  9.  * 
  10.  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
  11.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  12.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
  13.  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  14.  * 
  15.  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  16.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  17.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  18.  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
  19.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  20.  */
  21. #define NO_SANITY_CHECKS
  22. #include <assert.h>
  23. #include "video.h"
  24. #include "decoders.h"
  25.  
  26.  
  27. extern int zigzag_direct[];
  28.  
  29. /* Macro for returning 1 if num is positive, -1 if negative, 0 if 0. */
  30.  
  31. #define Sign(num) ((num > 0) ? 1 : ((num == 0) ? 0 : -1))
  32.  
  33.  
  34. /*
  35.  *--------------------------------------------------------------
  36.  *
  37.  * ParseReconBlock --
  38.  *
  39.  *    Parse values for block structure from bitstream.
  40.  *      n is an indication of the position of the block within
  41.  *      the macroblock (i.e. 0-5) and indicates the type of 
  42.  *      block (i.e. luminance or chrominance). Reconstructs
  43.  *      coefficients from values parsed and puts in 
  44.  *      block.dct_recon array in vid stream structure.
  45.  *      sparseFlag is set when the block contains only one
  46.  *      coeffictient and is used by the IDCT.
  47.  *
  48.  * Results:
  49.  *    dct_recon is filled with coefficients forming the block.
  50.  *
  51.  * Side effects:
  52.  *      Bit stream irreversibly parsed.
  53.  *
  54.  *--------------------------------------------------------------
  55.  */
  56.  
  57. #define DCT_recon blockPtr->dct_recon
  58. #define DCT_dc_y_past blockPtr->dct_dc_y_past
  59. #define DCT_dc_cr_past blockPtr->dct_dc_cr_past
  60. #define DCT_dc_cb_past blockPtr->dct_dc_cb_past
  61.  
  62. #define DECODE_DCT_COEFF_FIRST DecodeDCTCoeffFirst
  63. #define DECODE_DCT_COEFF_NEXT DecodeDCTCoeffNext
  64.  
  65. int 
  66. ParseReconBlock(n, sparseFlag)
  67.      int n;
  68.      int *sparseFlag;
  69. {
  70.   unsigned int temp_curBits;
  71.   int temp_bitOffset;
  72.   int temp_bufLength;
  73.   unsigned int *temp_bitBuffer;
  74.   int retval;
  75.   Block *blockPtr = &curVidStream->block;
  76.  
  77.   if (bufLength < 100)
  78.     correct_underflow();
  79.  
  80.   temp_curBits = curBits;
  81.   temp_bitOffset = bitOffset;
  82.   temp_bufLength = bufLength;
  83.   temp_bitBuffer = bitBuffer;
  84.  
  85.   {
  86.  
  87.     register unsigned int curBits;
  88.     register int bitOffset;
  89.     register int bufLength;
  90.     register unsigned int *bitBuffer;
  91.  
  92.     int diff;
  93.     int size, level, i, run, pos;
  94.     short int *reconptr, coeff;
  95.     unsigned char *iqmatrixptr, *niqmatrixptr;
  96.     int qscale;
  97.  
  98.     curBits = temp_curBits;
  99.     bitOffset = temp_bitOffset;
  100.     bufLength = temp_bufLength;
  101.     bitBuffer = temp_bitBuffer;
  102.  
  103.     *sparseFlag = 0;
  104.  
  105.     reconptr = DCT_recon[0];
  106.  
  107.     /* 
  108.      * Hand coded version of memset that's a little faster...
  109.      * Old call:
  110.      *    memset((char *) DCT_recon, 0, 64*sizeof(short int));
  111.      */
  112.     {
  113. /*old code */
  114. /*    short int *p;
  115.     int j;
  116.     p =  reconptr;
  117.     for (j=0; j<64; j++)
  118.     *p++ = 0;*/
  119. /* patch -pk */
  120.     long *p = (long *)reconptr;
  121.      p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = p[6] = p[7] = p[8] = p[9] =
  122.      p[10]= p[11]= p[12]= p[13]= p[14]= p[15]= p[16]= p[17]= p[18]= p[19]=
  123.      p[20]= p[21]= p[22]= p[23]= p[24]= p[25]= p[26]= p[27]= p[28]= p[29]=
  124.         p[30]= p[31]= 0;
  125.     }
  126.  
  127.     if (curVidStream->mblock.mb_intra) {
  128.  
  129.       if (n < 4) {
  130.  
  131.     DecodeDCTDCSizeLum(&size);
  132.  
  133.     if (size != 0) {
  134.       get_bitsn(size, &diff);
  135.           if (!(diff & bitTest[32-size])) {
  136.         diff = rBitMask[size] | (diff + 1);
  137.       }
  138.     }
  139.     else diff = 0;
  140.  
  141.     if (n == 0) {
  142.       coeff = diff << 3;
  143.       if (curVidStream->mblock.mb_address -
  144.           curVidStream->mblock.past_intra_addr > 1) 
  145.         coeff += 1024;
  146.       else coeff += DCT_dc_y_past;
  147.       DCT_dc_y_past = coeff;
  148.       *reconptr = coeff;
  149.       (*sparseFlag)++;
  150.     }
  151.     else {
  152.       coeff = DCT_dc_y_past + (diff << 3);
  153.       *reconptr = coeff;
  154.       (*sparseFlag)++;
  155.       DCT_dc_y_past = coeff;
  156.     }
  157.       }
  158.       
  159.       else {
  160.     
  161.     DecodeDCTDCSizeChrom(&size);
  162.     
  163.     if (size != 0) {
  164.       get_bitsn(size, &diff);
  165.           if (!(diff & bitTest[32-size])) {
  166.         diff = rBitMask[size] | (diff + 1);
  167.       }
  168.     }
  169.     else diff = 0;
  170.     
  171.     if (n == 4) {
  172.       coeff = diff << 3;
  173.       if (curVidStream->mblock.mb_address -
  174.           curVidStream->mblock.past_intra_addr > 1) 
  175.         coeff += 1024;
  176.       else coeff += DCT_dc_cr_past;
  177.       DCT_dc_cr_past = coeff;
  178.       *reconptr = coeff;
  179.       (*sparseFlag)++;
  180.     }
  181.     else {
  182.       coeff = diff << 3;
  183.       if (curVidStream->mblock.mb_address -
  184.           curVidStream->mblock.past_intra_addr > 1) 
  185.         coeff += 1024;
  186.       else coeff += DCT_dc_cb_past;
  187.       DCT_dc_cb_past = coeff;
  188.       *reconptr = coeff;
  189.       (*sparseFlag)++;
  190.     }
  191.       }
  192.       
  193.       i = 0; pos = 0;
  194.     
  195.       if (curVidStream->picture.code_type != 4) {
  196.     
  197.     qscale = curVidStream->slice.quant_scale;
  198.     iqmatrixptr = curVidStream->intra_quant_matrix[0];
  199.     
  200.     while(1) {
  201.       
  202.       DECODE_DCT_COEFF_NEXT(&run, &level);
  203.  
  204.       if (run == END_OF_BLOCK) break;
  205.  
  206.       i = i + run + 1;
  207.       
  208.       if (i > 63) {
  209.         retval = SKIP_TO_START_CODE;
  210.         goto end;
  211.       }
  212.       pos = zigzag_direct[i];
  213.       
  214.       coeff = (level * qscale * ((int) (*(iqmatrixptr+pos))))
  215.         >> 3;
  216.       if ((coeff & 1) == 0) 
  217.         coeff -= Sign(coeff);
  218.       
  219.       if (coeff > 2047) coeff = 2047;
  220.       else if (coeff < -2048) coeff = -2048;
  221.       
  222.       *(reconptr+pos) = coeff;
  223.       (*sparseFlag)++;
  224.     }
  225.  
  226.     /* If only one coefficient, store position + 1 in sparseFlag,
  227.        otherwise reset to zero.
  228.     */
  229.     if (*sparseFlag == 1) *sparseFlag = pos+1;
  230.     else *sparseFlag = 0;
  231.  
  232.     flush_bits(2);
  233.     retval = PARSE_OK;
  234.     goto end;
  235.       }
  236.     }
  237.     
  238.     else {
  239.       
  240.       niqmatrixptr = curVidStream->non_intra_quant_matrix[0];
  241.       qscale = curVidStream->slice.quant_scale;
  242.       
  243.       DECODE_DCT_COEFF_FIRST(&run, &level);
  244.       i = run;
  245.       
  246.       pos = zigzag_direct[i];
  247.       
  248.       coeff = (((level<<1) + Sign(level)) * qscale * 
  249.            ((int) (*(niqmatrixptr+pos)))) >> 4; 
  250.       
  251.       if ((coeff & 1) == 0) 
  252.     coeff -= Sign(coeff);
  253.       
  254.       if (coeff > 2047) coeff = 2047;
  255.       else if (coeff < -2048) coeff = -2048;
  256.       
  257.       *(reconptr+pos) = coeff;
  258.       (*sparseFlag)++;
  259.  
  260.       if (curVidStream->picture.code_type != 4) {
  261.     
  262.     while(1) {
  263.       
  264.       DECODE_DCT_COEFF_NEXT(&run, &level);
  265.  
  266.       if (run == END_OF_BLOCK) break;
  267.  
  268.       i = i+run+1;
  269.       
  270.       if (i > 63) {
  271.         retval = SKIP_TO_START_CODE;
  272.         goto end;
  273.       }
  274.  
  275.       pos = zigzag_direct[i];
  276.       
  277.       coeff = (((level<<1) + Sign(level)) * qscale * 
  278.            ((int) (*(niqmatrixptr+pos)))) >> 4; 
  279.       
  280.       if ((coeff & 1) == 0) 
  281.         coeff -= Sign(coeff);
  282.       
  283.       if (coeff > 2047) coeff = 2047;
  284.       else if (coeff < -2048) coeff = -2048;
  285.       
  286.       *(reconptr+pos) = coeff;
  287.       (*sparseFlag)++;
  288.     }
  289.  
  290.     /* If only one coefficient, store which one in sparseFlag,
  291.        otherwise reset to zero.
  292.     */
  293.     if (*sparseFlag == 1) *sparseFlag = pos+1;
  294.     else *sparseFlag = 0;
  295.     
  296.     flush_bits(2);
  297.     retval =  PARSE_OK;
  298.     goto end;
  299.       }
  300.     }
  301.     
  302.     retval = PARSE_OK;
  303.  
  304.   end:
  305.  
  306.     temp_curBits = curBits;
  307.     temp_bitOffset = bitOffset;
  308.     temp_bufLength = bufLength;
  309.     temp_bitBuffer = bitBuffer;
  310.  
  311.   }
  312.  
  313.   curBits = temp_curBits;
  314.   bitOffset = temp_bitOffset;
  315.   bufLength = temp_bufLength;
  316.   bitBuffer = temp_bitBuffer;
  317.  
  318.   return retval;
  319. }
  320.     
  321. #undef DCT_recon 
  322. #undef DCT_dc_y_past 
  323. #undef DCT_dc_cr_past 
  324. #undef DCT_dc_cb_past 
  325.  
  326.  
  327. /*
  328.  *--------------------------------------------------------------
  329.  *
  330.  * ParseAwayBlock --
  331.  *
  332.  *    Parses off block values, throwing them away.
  333.  *      Used with grayscale dithering.
  334.  *
  335.  * Results:
  336.  *    None.
  337.  *
  338.  * Side effects:
  339.  *      None.
  340.  *
  341.  *--------------------------------------------------------------
  342.  */
  343.  
  344. int 
  345. ParseAwayBlock(n)
  346.      int n;
  347. {
  348.   unsigned int diff;
  349.   unsigned int size, run;
  350.   int level;
  351.  
  352.   if (bufLength < 100)
  353.     correct_underflow();
  354.  
  355.   if (curVidStream->mblock.mb_intra) {
  356.  
  357.     /* If the block is a luminance block... */
  358.  
  359.     if (n < 4) {
  360.  
  361.       /* Parse and decode size of first coefficient. */
  362.  
  363.       DecodeDCTDCSizeLum(&size);
  364.  
  365.       /* Parse first coefficient. */
  366.  
  367.       if (size != 0) {
  368.     get_bitsn(size, &diff);
  369.       }
  370.     }
  371.  
  372.     /* Otherwise, block is chrominance block... */
  373.  
  374.     else {
  375.  
  376.       /* Parse and decode size of first coefficient. */
  377.  
  378.       DecodeDCTDCSizeChrom(&size);
  379.  
  380.       /* Parse first coefficient. */
  381.  
  382.       if (size != 0) {
  383.     get_bitsn(size, &diff);
  384.       }
  385.     }
  386.   }
  387.  
  388.   /* Otherwise, block is not intracoded... */
  389.  
  390.   else {
  391.  
  392.     /* Decode and set first coefficient. */
  393.  
  394.     DECODE_DCT_COEFF_FIRST(&run, &level);
  395.   }
  396.  
  397.   /* If picture is not D type (i.e. I, P, or B)... */
  398.  
  399.   if (curVidStream->picture.code_type != 4) {
  400.  
  401.     /* While end of macroblock has not been reached... */
  402.  
  403.     while (1) {
  404.  
  405.       /* Get the dct_coeff_next */
  406.  
  407.       DECODE_DCT_COEFF_NEXT(&run, &level);
  408.  
  409.       if (run == END_OF_BLOCK) break;
  410.     }
  411.  
  412.     /* End_of_block */
  413.  
  414.     flush_bits(2);
  415.   }
  416.  
  417.   return PARSE_OK;
  418. }
  419.  
  420.